package ex;

import org.apache.commons.math3.util.CombinatoricsUtils;

import java.util.Arrays;

/**
 * @Description 用于处理下标构成的集合中抽取指定顺序的组合
 * @Date 2022/3/20 17:20
 * @Author eric ling
 */
public class ArrayHandler {


    /**
     * 将第combIdx组的stuffer填充到hugeArray的末尾
     *
     */
    public static void fillToArray(byte[] hugeArray, byte[] stuffer, int combIdx) {
        System.arraycopy(stuffer, 0, hugeArray, combIdx * stuffer.length, stuffer.length);
    }


    /**
     * 根据组合数组中想要的顺序索引从 idxsArray 中抽取出的对应的元素，抽取后修改为false表示不在该集合中
     *
     * @param idxsArray   数组元素为true构成的集合
     * @param combination 元素递增的 一个有序组合
     * @return 根据组合数组中想要的顺序索引从 idxsArray 中抽取出的对应的元素
     */
    public static byte[] extractCombElementB(boolean[] idxsArray, int[] combination) {
        int c = 0; // 待匹配combination中的元素下标
        int order = -1; // 当前元素的序号
        byte[] nums = new byte[combination.length];
        for (byte i = 0; i < idxsArray.length && c < combination.length; i++) {
            if (idxsArray[i]) order++;
            if (order == combination[c]) {
                // 取出当前需要的值
                idxsArray[i] = false;
                nums[c++] = i;
            }
        }
        return nums;
    }

    /**
     * 根据组合数组中想要的顺序索引从 idxsArray 中抽取出的对应的元素，抽取后修改为false表示不在该集合中
     *
     * @param idxsArray   数组元素为true构成的集合
     * @param combination 元素递增的 一个有序组合
     * @return 根据组合数组中想要的顺序索引从 idxsArray 中抽取出的对应的元素
     */
    public static int[] extractCombElement(boolean[] idxsArray, int[] combination) {
        int c = 0; // 待匹配combination中的元素下标
        int order = -1; // 当前元素的序号
        int[] nums = new int[combination.length];
        for (int i = 0; i < idxsArray.length && c < combination.length; i++) {
            if (idxsArray[i]) order++;
            if (order == combination[c]) {
                // 取出当前需要的值
                idxsArray[i] = false;
                nums[c] = i;
                c++; // 匹配下一个需要的值
            }
        }
        return nums;
    }

    /**
     * 将 由布尔数组为true的元素对应下标构成的集合 取出前面size个元素 转化为int数组
     *
     * @param bools 由布尔数组为true的元素对应下标构成的集合
     * @param size  想要取出的元素的个数，个数不足则为0
     * @return 指定长度的int数组，超出部分为0
     */
    public static int[] boolToInt(boolean[] bools, int size) {
        int[] nums = new int[size];
        int i = 0;
        for (int j = 0; j < bools.length && i < size; j++) {
            if (bools[j]) nums[i++] = j;
        }
        return nums;
    }

    public static byte[] concatB(byte[] array1, byte[] array2) {
        byte[] result = Arrays.copyOf(array1, array1.length + array2.length);
        System.arraycopy(array2, 0, result, array1.length, array2.length);
        return result;
    }

    public static int[] concat(int[] array1, int[] array2) {
        int[] result = Arrays.copyOf(array1, array1.length + array2.length);
        System.arraycopy(array2, 0, result, array1.length, array2.length);
        return result;
    }


    /**
     * @return 将二元序列转化为等价集
     */
    public static int[] parse(int[] binSeq) {
        int[] nums = new int[binSeq.length];
        int idx = 0;
        for (int i = 0; i < binSeq.length; i++) {
            if (binSeq[i] == 1) {
                nums[idx++] = i;
            }
        }
        return Arrays.copyOf(nums, idx);
    }

    public static void main(String[] args) {
        long c1 = CombinatoricsUtils.binomialCoefficient(31, 6);
        long c2 = CombinatoricsUtils.binomialCoefficient(25, 5);
        long c3 = CombinatoricsUtils.binomialCoefficient(20, 0);
        System.out.println(c1 * c2 * c3);
    }
}
